package personnel.department.pages;

import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang3.tuple.Pair;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.DateTime;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Tracker;
import org.eclipse.swt.widgets.Widget;

import personnel.department.pages.widgets.AbstractWidget;
import personnel.department.utils.TranslatorUtils;

import com.google.common.base.Strings;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;

public class TwoColumnFieldsComposite extends ScrolledComposite {

	private List<Field> fields;
	private final List<Pair<String, AbstractWidget<?>>> widgetByName = Lists.newArrayList();
	private final Map<Field, AbstractWidget<?>> widgetByField = Maps.newHashMap();

	private ColumnContent leftColumnContent;
	private Composite leftColumn;
	private Composite rightColumn;
	private ColumnContent rightColumnContent;
	private boolean withSections;

	public TwoColumnFieldsComposite(Composite parent, List<Field> fields, int style) {
		super(parent, style | SWT.V_SCROLL | SWT.H_SCROLL);
		this.fields = fields;
	}

	public TwoColumnFieldsComposite(ScrolledComposite sc, List<Field> searchFields, int style, boolean withSections) {
		this(sc, searchFields, style);
		this.withSections = withSections;
	}

	public void createControl() {
		GridDataFactory.fillDefaults().grab(true, true).applyTo(this);
		Composite parent = createContent();
		setContent(parent);
	    setExpandVertical(true);
	    setExpandHorizontal(true);
	    addControlListener(new ControlAdapter() {
	      public void controlResized(ControlEvent e) {
	        setMinSize(parent.computeSize(SWT.DEFAULT, SWT.DEFAULT));
	      }
	    });
	}

	private Composite createContent() {
		Composite parent = new Composite(this, SWT.NONE);
		parent.setLayout(new GridLayout(2, false));
		parent.setLayoutData(GridDataFactory.fillDefaults().grab(true, true).create());

		Multimap<Class<?>, Field> fieldsByType = ArrayListMultimap.create();
		fields.stream().forEach(field -> fieldsByType.put(field.getDeclaringClass(), field));

		List<Field> leftColumnFelds = Lists.newArrayList();
		List<Field> rightColumnFields = Lists.newArrayList();
		setFields(fieldsByType, leftColumnFelds, rightColumnFields);


		createLeftColumn(parent, leftColumnFelds);
		createRightColumn(parent, rightColumnFields);
		return parent;
	}

	private void setFields(Multimap<Class<?>, Field> fieldsByType,
			List<Field> leftColumnFelds, List<Field> rightColumnFields) {
		if (withSections) {
			int size = fieldsByType.keySet().size();
			int count = 0;
			for (Class<?> type : fieldsByType.keySet()) {
				if (count < size/2) {
					leftColumnFelds.addAll(fieldsByType.get(type));
				} else {
					rightColumnFields.addAll(fieldsByType.get(type));
				}
				count++;
			}
		} else {
			int size = fields.size();
			leftColumnFelds.addAll(fields.subList(0, size/2));
			rightColumnFields.addAll(fields.subList(size/2, size));
		}
	}


	private void createLeftColumn(Composite c, List<Field> columnFelds) {
		leftColumn = new Composite(c, SWT.NONE);
		leftColumn.setLayout(GridLayoutFactory.swtDefaults().create());
		leftColumn.setLayoutData(GridDataFactory.fillDefaults().grab(false, true).create());

		leftColumnContent = new ColumnContent(leftColumn, columnFelds, withSections);
		leftColumnContent.createContent();
		widgetByName.addAll(leftColumnContent.getWidgetByName());
		widgetByField.putAll(leftColumnContent.getWidgetByField());
	}

	private void createRightColumn(Composite c, List<Field> columnFelds) {
		rightColumn = new Composite(c, SWT.NONE);
		rightColumn.setLayout(GridLayoutFactory.swtDefaults().create());
		rightColumn.setLayoutData(GridDataFactory.fillDefaults().grab(false, true).create());

		rightColumnContent = new ColumnContent(rightColumn, columnFelds, withSections);
		rightColumnContent.createContent();
		widgetByName.addAll(rightColumnContent.getWidgetByName());
		widgetByField.putAll(rightColumnContent.getWidgetByField());

	}

	public List<Pair<String, AbstractWidget<?>>> getWidgetByName() {
		return widgetByName;
	}

	public Composite getLeftColumn() {
		return leftColumn;
	}

	public Composite getRightColumn() {
		return rightColumn;
	}

	public Map<Field, Object> getWidgetValueByField() {
		Map<Field, AbstractWidget<?>> filterValues = Maps.filterValues(widgetByField, widget -> {
			return widget.isModify() ? true : false;
		});
		return Maps.transformValues(filterValues, widget -> widget.getValue());
	}

}
